package dj.tic;

import java.util.Scanner;

import dj.engine.events.LifecycleEvents;
import dj.engine.util.Vec2i;

public class TicState implements LifecycleEvents{
	
	private static final long TURN_LENGTH = 30_000_000_000l;
	private long turnTimer;
	
	public enum PlayerState{
		NONE, PLAYER_1, PLAYER_2;
		public String toString()
		{
			if(this == NONE)
			{
				return " ";
			}
			else if(this == PLAYER_1)
			{
				return "x";
			}
			else
			{
				return "o";
			}
		}
	}

	public enum Player
	{
		P1, P2;
		public String toString()
		{
			if(this == P1)
			{
				return "Player 1";
			}
			else if(this == P2)
			{
				return "Player 2";
			}
			return "";
		}
	}
	Player playersTurn;
	private PlayerState[][] gameBoard;
	public TicState(int size)
	{
		size = Math.max(size, 3);
		gameBoard = new PlayerState[size][size];
		for(int i = 0; i < size; ++i)
		{
			for(int j = 0; j < size; ++j)
			{
				gameBoard[i][j] = PlayerState.NONE;
			}
		}
		playersTurn = Player.P1;
	}

	public PlayerState getWinner()
	{
		if(checkWin(PlayerState.PLAYER_1))
		{
			return PlayerState.PLAYER_1;
		}
		else if(checkWin(PlayerState.PLAYER_2))
		{
			return PlayerState.PLAYER_2;
		}
		else
		{
			return PlayerState.NONE;
		}
	}

	private boolean checkWin(PlayerState toCheck)
	{
		for(int i = 0; i < gameBoard.length; ++i)
		{
			boolean good = true;
			for(int j = 0; j < gameBoard[i].length; ++j)
			{
				good = good && gameBoard[i][j] == toCheck;
			}
			if(good)
			{
				return true;
			}
		}
		for(int j = 0; j < gameBoard[0].length; ++j)
		{
			boolean good = true;
			for(int i = 0; i < gameBoard.length; ++i)
			{
				good = good && gameBoard[i][j] == toCheck;
			}
			if(good)
			{
				return true;
			}
		}
		boolean good = true;
		for(int i = 0; i < gameBoard.length; ++i)
		{
			good = good && gameBoard[i][i] == toCheck;
		}
		if(good)
		{
			return true;
		}
		good = true;
		for(int i = 0; i < gameBoard.length; ++i)
		{
			good = good && gameBoard[i][gameBoard.length - 1 - i] == toCheck;
		}
		if(good)
		{
			return true;
		}
		return false;
	}

	void receiveMovement(Vec2i loc)
	{
		assert(loc.x < gameBoard.length);
		assert(loc.y < gameBoard[0].length);
		gameBoard[loc.x][loc.y] = (playersTurn == Player.P1)?PlayerState.PLAYER_1:PlayerState.PLAYER_2; 
	}

	void advanceTurn()
	{
		playersTurn = (playersTurn == Player.P1)?Player.P2:Player.P1;
	}

	public String toString()
	{
		StringBuilder sb = new StringBuilder();
		for(int i = 0; i < gameBoard.length; ++i)
		{
			for(int j = 0; j < gameBoard[i].length; ++j)
			{
				sb.append(gameBoard[i][j]);
				if(j != gameBoard[i].length - 1)
				{
					sb.append("|");
				}
			}
			sb.append("\n");
			if(i != gameBoard.length - 1)
			{
				sb.append("-----\n");
			}
		}
		return sb.toString();
	}
		
	public void timeElapsed(long t)
	{
		turnTimer -= t;
		if(turnTimer <= 0l)
		{
			this.advanceTurn();
			turnTimer = TicState.TURN_LENGTH;
		}
	}

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onStart() {
		// TODO Auto-generated method stub
		this.turnTimer = TicState.TURN_LENGTH;
	}

	@Override
	public void onStop() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onPause() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onUnpause() {

		// TODO Auto-generated method stub
		
	}
	/**
	 * Text based tic tac toe
	 * @param args
	 */
	public static void main(String[] args)
	{
		@SuppressWarnings("resource")
		Scanner stdin = new Scanner(System.in);
		TicState game = new TicState(3);
		boolean toContinue = true;
		System.out.println(game);
		while(toContinue)
		{
			String[] tokens = stdin.nextLine().split(" ");
			Vec2i move = new Vec2i(Integer.parseInt(tokens[0]), Integer.parseInt(tokens[1]));
			game.receiveMovement(move);
			System.out.println(game);
			PlayerState win = game.getWinner();
			if(win == PlayerState.PLAYER_1)
			{
				System.out.println("Player 1 wins");
				toContinue = false;
			}
			else if(win == PlayerState.PLAYER_2)
			{
				System.out.println("Player 2 wins");
				toContinue = false;
			}
			game.advanceTurn();
		}
	}

	public String getTurnStatus()
	{
		return "Player's turn is: " + playersTurn + "\n";
	}
	
	public String getTimeStatus()
	{
		return "Time left in turn: " + turnTimer/1_000_000_000 + "\n";
	}
	
}
